using System;
using System.Collections.Generic;
using System.Text;
using RapidHDL.Fabric;

namespace RapidHDL
{
    class FabricTest : FabricComponent 
    {
        public FabricTest(Component poParentComponent, string psName, ClockComponent poClock, NodeVector pnvReset)
            : base(poParentComponent, psName, poClock, pnvReset)
        {

        }

        public override void DefineFabric()
        {
            ContainerBlock.CreateALU("INC", ALUType.Inc, 4);
            ContainerBlock.CreateALU("ADD", ALUType.Add, 4);
            ContainerBlock.CreateALU("SUB", ALUType.Subtract, 4);
            ContainerBlock.CreateRegister("A", 4, true);
            ContainerBlock.CreateRegister("B", 4, true);
            ContainerBlock.CreateRegister("X", 4, true);
            ContainerBlock.CreateExternalInput("IN", 4);
            ContainerBlock.CreateExternalOutput("OUT", 4);
            ControlState oControl;

            ContainerBlock.Join("X", "OUT", "OUT", "IN");

            // LOADA
            oControl = ContainerBlock.CreateControlState("LOADA");
            oControl.Join("IN", "OUT", "A", "IN");
            oControl.Activate("A", "LATCH");

            // LOADB
            oControl = ContainerBlock.CreateControlState("LOADB");
            oControl.Join("IN", "OUT", "B", "IN");
            oControl.Activate("B", "LATCH");

            // ATOB
            oControl = ContainerBlock.CreateControlState("ATOB");
            oControl.Join("A", "OUT", "B", "IN");
            oControl.Activate("B", "LATCH");

            //BTOA
            oControl = ContainerBlock.CreateControlState("BTOA");
            oControl.Join("B", "OUT", "A", "IN");
            oControl.Activate("A", "LATCH");

            //ATOX
            oControl = ContainerBlock.CreateControlState("ATOX");
            oControl.Join("A", "OUT", "X", "IN");
            oControl.Activate("X", "LATCH");

            //XTOA
            oControl = ContainerBlock.CreateControlState("XTOA");
            oControl.Join("X", "OUT", "A", "IN");
            oControl.Activate("A", "LATCH");

            //INCA
            oControl = ContainerBlock.CreateControlState("INCA");
            oControl.Join("A", "OUT", "INC", "IN");
            oControl.Join("INC", "OUT", "A", "IN");
            oControl.Activate("A", "LATCH");

            //ADD
            oControl = ContainerBlock.CreateControlState("ADD");
            oControl.Join("A", "OUT", "ADD", "IN");
            oControl.Join("B", "OUT", "ADD", "IN2");
            oControl.Join("ADD", "OUT", "X", "IN");
            oControl.Activate("X", "LATCH");

            //SUB
            oControl = ContainerBlock.CreateControlState("SUB");
            oControl.Join("A", "OUT", "SUB", "IN");
            oControl.Join("B", "OUT", "SUB", "IN2");
            oControl.Join("SUB", "OUT", "X", "IN");
            oControl.Activate("X", "LATCH");

        }
    }
}
